/*
 * $Log $
 * 
 */

package soccerscope.util;

import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;

import soccerscope.model.ClientScene;
import soccerscope.model.GameEvent;
import soccerscope.model.SceneSet;
import soccerscope.util.analyze.BackPassAnalyzer;
import soccerscope.util.analyze.BallAverageAnalyzer;
import soccerscope.util.analyze.BallPossessionAnalyzer;
import soccerscope.util.analyze.CornerKickAnalyzer;
import soccerscope.util.analyze.DribbleAnalyzer;
import soccerscope.util.analyze.FreeKickAnalyzer;
import soccerscope.util.analyze.FreeKickFaultAnalyzer;
import soccerscope.util.analyze.GoalAnalyzer;
import soccerscope.util.analyze.GoalKickAnalyzer;
import soccerscope.util.analyze.GoalieCatchAnalyzer;
import soccerscope.util.analyze.KickInAnalyzer;
import soccerscope.util.analyze.LostBallAnalyzer;
import soccerscope.util.analyze.OffsideAnalyzer;
import soccerscope.util.analyze.PassAnalyzer;
import soccerscope.util.analyze.PassChainAnalyzer;
import soccerscope.util.analyze.PassDistAnalyzer;
import soccerscope.util.analyze.PassMissAnalyzer;
import soccerscope.util.analyze.PassVelAnalyzer;
import soccerscope.util.analyze.PassXAnalyzer;
import soccerscope.util.analyze.SceneAnalyzer;
import soccerscope.util.analyze.ShootAnalyzer;
import soccerscope.util.analyze.TopXAnalyzer;

public class GameAnalyzer {

  private static ArrayList<SceneAnalyzer> analyzerList;

  private final static String             colName[] = { " ", "Left Team", "Right Team" };

  private GameAnalyzer() {

  };

  static {
    GameAnalyzer.analyzerList = new ArrayList<SceneAnalyzer>();
    GameAnalyzer.analyzerList.add(new GoalAnalyzer());
    GameAnalyzer.analyzerList.add(new ShootAnalyzer());
    GameAnalyzer.analyzerList.add(new DribbleAnalyzer());
    GameAnalyzer.analyzerList.add(new GoalieCatchAnalyzer());
    GameAnalyzer.analyzerList.add(new GoalKickAnalyzer());
    GameAnalyzer.analyzerList.add(new OffsideAnalyzer());
    GameAnalyzer.analyzerList.add(new BackPassAnalyzer());
    GameAnalyzer.analyzerList.add(new CornerKickAnalyzer());
    GameAnalyzer.analyzerList.add(new FreeKickAnalyzer());
    GameAnalyzer.analyzerList.add(new FreeKickFaultAnalyzer());
    GameAnalyzer.analyzerList.add(new KickInAnalyzer());
    GameAnalyzer.analyzerList.add(new BallPossessionAnalyzer());
    GameAnalyzer.analyzerList.add(new PassAnalyzer());
    GameAnalyzer.analyzerList.add(new PassMissAnalyzer());
    GameAnalyzer.analyzerList.add(new LostBallAnalyzer());
    GameAnalyzer.analyzerList.add(new PassXAnalyzer());
    GameAnalyzer.analyzerList.add(new TopXAnalyzer());
    GameAnalyzer.analyzerList.add(new PassDistAnalyzer());
    GameAnalyzer.analyzerList.add(new PassVelAnalyzer());
    GameAnalyzer.analyzerList.add(new PassChainAnalyzer());
    GameAnalyzer.analyzerList.add(new BallAverageAnalyzer());
  }

  private static void init() {

    Iterator it = GameAnalyzer.analyzerList.iterator();
    while (it.hasNext()) {
      ((SceneAnalyzer) it.next()).init();
    }
  }

  public static ArrayList<GameEvent> analyze(SceneSet set) {

    ArrayList<GameEvent> eventList = new ArrayList<GameEvent>();
    Iterator sceneit = set.iterator();
    ClientScene clientScene = null;
    ClientScene prev = null;
    GameEvent ge;

    GameAnalyzer.init();
    while (sceneit.hasNext()) {
      prev = clientScene;
      clientScene = (ClientScene) sceneit.next();
      Iterator it = GameAnalyzer.analyzerList.iterator();
      while (it.hasNext()) {
        ge = ((SceneAnalyzer) it.next()).analyze(clientScene, prev);
        if (ge != null && !eventList.contains(ge)) {
          eventList.add(ge);
        }
      }
    }
    return eventList;
  }

  public static SceneAnalyzer getAnalyzer(String name) {

    Iterator it = GameAnalyzer.analyzerList.iterator();
    while (it.hasNext()) {
      SceneAnalyzer sa = (SceneAnalyzer) it.next();
      if (name.compareTo(sa.getName()) == 0) {
        return sa;
      }
    }
    return null;
  }

  public static TableModel getTableModel() {

    TableModel dataModel = new AbstractTableModel() {

      private static final long serialVersionUID = -7927210501116649147L;

      @Override
      public String getColumnName(int col) {

        switch (col) {
          case SceneAnalyzer.ROW_NAME:
          case SceneAnalyzer.LEFT:
          case SceneAnalyzer.RIGHT:
            return GameAnalyzer.colName[col];
          default:
            return " ";
        }
      }

      public int getColumnCount() {

        return SceneAnalyzer.COL_MAX;
      }

      public int getRowCount() {

        return GameAnalyzer.analyzerList.size();
      }

      public Object getValueAt(int row,
          int col) {

        return ((SceneAnalyzer) GameAnalyzer.analyzerList.get(row))
            .getValueAt(col);
      }
    };

    return dataModel;
  }

  public final static int timeSlice = 1000;

  public static TableModel getLeftTableModel() {

    TableModel dataModel = new AbstractTableModel() {

      private static final long serialVersionUID = -1688649502638591952L;

      @Override
      public String getColumnName(int col) {

        if (col == 0) {
          return " ";
        }
        return ((col - 1) * GameAnalyzer.timeSlice + 1) + " - " + (col * GameAnalyzer.timeSlice);
      }

      public int getColumnCount() {

        return Time.GAME_TIME / GameAnalyzer.timeSlice + 1;
      }

      public int getRowCount() {

        return GameAnalyzer.analyzerList.size();
      }

      public Object getValueAt(int row,
          int col) {

        if (col == 0) {
          return ((SceneAnalyzer) GameAnalyzer.analyzerList.get(row))
              .getValueAt(col);
        }
        return ((SceneAnalyzer) GameAnalyzer.analyzerList.get(row))
            .getLeftValueAt(((col - 1) * GameAnalyzer.timeSlice + 1),
                (col * GameAnalyzer.timeSlice));
      }
    };

    return dataModel;
  }

  public static TableModel getRightTableModel() {

    TableModel dataModel = new AbstractTableModel() {

      private static final long serialVersionUID = -7995033203508524075L;

      @Override
      public String getColumnName(int col) {

        if (col == 0) {
          return " ";
        }
        return ((col - 1) * GameAnalyzer.timeSlice + 1) + " - " + (col * GameAnalyzer.timeSlice);
      }

      public int getColumnCount() {

        return Time.GAME_TIME / GameAnalyzer.timeSlice + 1;
      }

      public int getRowCount() {

        return GameAnalyzer.analyzerList.size();
      }

      public Object getValueAt(int row,
          int col) {

        if (col == 0) {
          return ((SceneAnalyzer) GameAnalyzer.analyzerList.get(row))
              .getValueAt(col);
        }
        return ((SceneAnalyzer) GameAnalyzer.analyzerList.get(row))
            .getRightValueAt(((col - 1) * GameAnalyzer.timeSlice + 1),
                (col * GameAnalyzer.timeSlice));
      }
    };

    return dataModel;
  }
}
